package net.tv90.volunteerserveradmin.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import net.tv90.volunteerserveradmin.annotation.AccessLimit;
import net.tv90.volunteerserveradmin.constant.RoleConstant;
import net.tv90.volunteerserveradmin.manager.SMSCodeManager;
import net.tv90.volunteerserveradmin.model.dto.*;
import net.tv90.volunteerserveradmin.model.vo.UserStatusVO;
import net.tv90.volunteerserveradmin.model.vo.UserVO;
import net.tv90.volunteerserveradmin.service.UserService;
import net.tv90.volunteerserveradmin.utils.entity.PageResult;
import net.tv90.volunteerserveradmin.utils.entity.Result;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Validated
@CrossOrigin
@RestController
@RequestMapping("user")
@Tag(name = "用户管理接口")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private SMSCodeManager smsCodeManager;

    @GetMapping("/status")
    @Operation(summary = "获取用户登录信息", description = "用户获取用户信息，包含用户身份")
    public Result<UserStatusVO> getUserStatus() {
        return Result.success(userService.getUserStatus());
    }

    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户通过用户名或和密码进行登录")
    public Result<UserStatusVO> loginUser(@RequestParam String username, @RequestParam String password) {
        return Result.success(userService.login(username, password));
    }

    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "用户进行注册，提供用户名、密码和邮箱")
    public Result<Void> registerUser(@RequestBody UserRegisterDTO dto) {
        userService.register(dto);
        return Result.success();
    }

    @GetMapping("/logout")
    @SaCheckLogin
    @Operation(summary = "用户登出", description = "已登录用户退出系统")
    public Result<Void> logoutUser() {
        userService.logout();
        return Result.success();
    }

    @PostMapping("/verify")
    @SaCheckLogin
    @Operation(summary = "用户认证", description = "用户进行实名认证，绑定角色")
    public Result<Void> verifyUser(@RequestBody UserVerifyDTO dto) {
        userService.verify(dto);
        return Result.success();
    }

    @GetMapping("/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @Operation(summary = "根据id获取用户信息", description = "根据用户ID获取用户详细信息")
    public Result<UserVO> getUserById(@PathVariable Long id) {
        return Result.success(userService.getUserById(id));
    }

    @PostMapping("/query")
    @SaCheckRole(RoleConstant.ADMIN)
    @Operation(summary = "查询用户信息", description = "获取所有用户的简要信息，支持分页和条件查询")
    public Result<PageResult<UserVO>> queryUsers(@RequestBody UserQueryDTO dto) {
        return Result.success(userService.queryUsers(dto));
    }

    @PostMapping("/add")
    @SaCheckRole(RoleConstant.ADMIN)
    @Operation(summary = "添加用户", description = "添加新的用户信息")
    public Result<Void> addUser(@RequestBody UserDTO dto) {
        userService.addUser(dto);
        return Result.success();
    }

    @PutMapping("/update/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @Operation(summary = "更新用户信息", description = "根据用户ID更新用户信息")
    public Result<Void> updateUser(@PathVariable Long id, @RequestBody UserDTO dto) {
        userService.updateUser(id, dto);
        return Result.success();
    }

    @DeleteMapping("/delete/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @Operation(summary = "删除用户", description = "根据用户ID删除用户")
    public Result<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return Result.success();
    }

    @GetMapping("/self")
    @SaCheckLogin
    @Operation(summary = "用户获取自己信息", description = "用户获取自己详细信息")
    public Result<UserVO> getUserSelfById() {
        return Result.success(userService.getUserSelfById());
    }

    @AccessLimit(seconds = 60, maxCount = 1)
    @GetMapping("/email/{email}")
    @Operation(summary = "发送邮箱验证码", description = "用户注册时，发送邮箱验证码")
    public Result<Void> getCode(@PathVariable @Email String email) {
        smsCodeManager.sendCodeToEmail(email);
        return Result.success();
    }

    @AccessLimit(seconds = 60, maxCount = 1)
    @GetMapping("/send-code/{email}")
    @Operation(summary = "发送找回密码验证码", description = "通过邮箱发送找回密码的验证码")
    public Result<Void> sendResetCode(@PathVariable @Email String email) {
        smsCodeManager.sendResetPasswordCodeToEmail(email);
        return Result.success();
    }

    @PostMapping("/reset")
    @Operation(summary = "通过验证码重置密码", description = "用户通过邮箱验证码重置密码")
    public Result<Void> resetPassword(@RequestBody ResetPasswordDTO dto) {
        userService.resetPassword(dto);
        return Result.success();
    }

    @SaCheckLogin
    @PostMapping("/change")
    @Operation(summary = "已登录用户修改密码", description = "已登录用户通过旧密码修改为新密码")
    public Result<Void> changePassword(
            @RequestParam @NotBlank String oldPassword,
            @RequestParam @NotBlank String newPassword
    ) {
        userService.changePassword(oldPassword, newPassword);
        return Result.success();
    }
}
